package com.github.niefy.common.utils;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.time.Duration;
import java.time.Instant;
import java.util.Map;

/**
 * @author : [86188]
 * @description : [一句话描述该类的功能]
 * @createTime : [2022/10/12 10:33]
 * @updateUser : [86188]
 * @updateTime : [2022/10/12 10:33]
 */
public class JWTUtils {
    private static final String SECRET = "OfficialAccountsToken*!@&&&^#";//加盐密钥
    private static final long defPeriodValidity = 60 * 60;//默认有效时间
    private static final long nearExpiration = 60 * 10;//临期时间

    /**
     * map生成token
     */
    public static String getToken(Map<String, Object> map) {
        JWTCreator.Builder builder = JWT.create();

        //payload
        map.forEach((k,v) ->{
            if (v!=null) {
                builder.withClaim(k,v.toString());
            }

        });

        Instant instant = Instant.now().plusSeconds(defPeriodValidity);

        builder.withExpiresAt(instant);//指定令牌的过期时间
        String token = builder.sign(Algorithm.HMAC256(SECRET));//签名
        return token;
    }

    /**
     * string生成token
     */
    public static String getToken(String name, String value) {
        JWTCreator.Builder builder = JWT.create();
        builder.withClaim(name, value);

        Instant instant = Instant.now().plusSeconds(defPeriodValidity);

        builder.withExpiresAt(instant);//指定令牌的过期时间
        String token = builder.sign(Algorithm.HMAC256(SECRET));//签名
        return token;
    }

    /**
     * 验证token
     */
    public static DecodedJWT verify(String token) {
        //如果有任何验证异常，此处都会抛出异常
        return JWT.require(Algorithm.HMAC256(SECRET)).build().verify(token);
    }
    /**
     * 刷新token
     * */
    public static String renewalToken(DecodedJWT jwtObj){
        Instant newExpInstant = null;
        String newToken;
        newExpInstant = Instant.now().plusSeconds(defPeriodValidity);
        JWTCreator.Builder builder = JWT.create();
        jwtObj.getClaims().forEach((k, v)->{
            builder.withClaim(k,v.asString());
        });
        builder.withExpiresAt(newExpInstant);//指定令牌的过期时间
        newToken = builder.sign(Algorithm.HMAC256(SECRET));//签名
        return newToken;
    }
    /**
     * 判断token是否临近过期
     * */
    public static Boolean checkTokenExpires(DecodedJWT jwtObj){
        Instant expInstant = jwtObj.getExpiresAtAsInstant();
        Instant now = Instant.now();
        long remainTime = Duration.between(expInstant, now).toSeconds();
        //剩余有效时间小于默认临期时间
        return remainTime < nearExpiration;
    }
}
